import java.util.Iterator;
import java.util.List;
import java.util.Properties;

import aima.core.agent.Action;
import aima.core.environment.eightpuzzle.EightPuzzleBoard;
import aima.core.environment.eightpuzzle.EightPuzzleFunctionFactory;
import aima.core.environment.eightpuzzle.EightPuzzleGoalTest;
import aima.core.environment.eightpuzzle.ManhattanHeuristicFunction;
import aima.core.environment.eightpuzzle.MisplacedTilleHeuristicFunction;
import aima.core.search.framework.GraphSearch;
import aima.core.search.framework.Problem;
import aima.core.search.framework.Search;
import aima.core.search.framework.SearchAgent;
import aima.core.search.informed.AStarSearch;
import aima.core.search.uninformed.DepthLimitedSearch;
import aima.core.search.uninformed.IterativeDeepeningSearch;


public class SegundoPunto {

	static EightPuzzleBoard boardWithThreeMoveSolution = new EightPuzzleBoard(
			new int[] { 1, 2, 5, 3, 4, 0, 6, 7, 8 });;

	static EightPuzzleBoard random1 = new EightPuzzleBoard(new int[] { 1, 4, 2,
			7, 5, 8, 3, 0, 6 });

	static EightPuzzleBoard extreme = new EightPuzzleBoard(new int[] { 0, 8, 7,
			6, 5, 4, 3, 2, 1 });
	
	

		private static void eightPuzzleAStarDemo(EightPuzzleBoard estado) {
			System.out
					.println("\nEightPuzzleDemo AStar Search (MisplacedTileHeursitic)-->");
			try {
				Problem problem = new Problem(estado, EightPuzzleFunctionFactory
						.getActionsFunction(), EightPuzzleFunctionFactory
						.getResultFunction(), new EightPuzzleGoalTest());
				Search search = new AStarSearch(new GraphSearch(),
						new MisplacedTilleHeuristicFunction());
				SearchAgent agent = new SearchAgent(problem, search);
				printActions(agent.getActions());
				printInstrumentation(agent.getInstrumentation());
			} catch (Exception e) {
				e.printStackTrace();
			}

		}


		private static void eightPuzzleAStarManhattanDemo(EightPuzzleBoard estado) {
			System.out
					.println("\nEightPuzzleDemo AStar Search (ManhattanHeursitic)-->");
			try {
				Problem problem = new Problem(estado, EightPuzzleFunctionFactory
						.getActionsFunction(), EightPuzzleFunctionFactory
						.getResultFunction(), new EightPuzzleGoalTest());
				Search search = new AStarSearch(new GraphSearch(),
						new ManhattanHeuristicFunction());
				SearchAgent agent = new SearchAgent(problem, search);
				printActions(agent.getActions());
				printInstrumentation(agent.getInstrumentation());
			} catch (Exception e) {
				e.printStackTrace();
			}

	}
	
	private static void printInstrumentation(Properties properties) {
		Iterator<Object> keys = properties.keySet().iterator();
		while (keys.hasNext()) {
			String key = (String) keys.next();
			String property = properties.getProperty(key);
			System.out.println(key + " : " + property);
		}

	}

	private static void printActions(List<Action> actions) {
		for (int i = 0; i < actions.size(); i++) {
			String action = actions.get(i).toString();
			System.out.println(action);
		}
	}
	
	public static void main(String[] args){
		
		/*Ejecuta por parametros asignados en la llamada*/
		/*1: estado boardWithThreeMoveSolution*/
		/*2: estado random1*/
		/*3: estado extreme*/
		try{
				int inicial;
				if (args[0].equals("1") || args[0].equals("2") || args[0].equals("3")){
					inicial = Integer.parseInt(args[0]);
					EightPuzzleBoard estado;
			
					if (inicial == 1)
						estado = boardWithThreeMoveSolution;
					else if (inicial == 2)
						estado = random1;
					else 
						estado = extreme;
		
					eightPuzzleAStarDemo(estado);
					eightPuzzleAStarManhattanDemo(estado);
				}
				else
					System.out.println("Error al especificar el estado inicial");	

		}
		catch
			(Exception e){
			System.out.println("Error. Debe especificar un estado inicial");
			}
		
	}

}
